package com.sduept.nwld.dataserver.controller.config;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.NodeExpandEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;
import org.primefaces.model.TreeNode;
import org.springframework.beans.factory.annotation.Autowired;

import com.sduept.bigdata.fault.common.ParamDesc;
import com.sduept.bigdata.risk.service.RiskAlarmMessageQueryManager;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.cim.ledger.enums.ManagementUnitEnum;
import com.sduept.cim.ledger.manager.SubstationLedgerManager;
import com.sduept.cim.ledger.model.SubstationLedger;
import com.sduept.cim.model.core.Equipment;
import com.sduept.cim.model.core.Substation;
import com.sduept.cim.model.protection.ProtectionEquipment;
import com.sduept.cim.model.wires.ACLineSegment;
import com.sduept.cim.model.wires.Breaker;
import com.sduept.cim.model.wires.BusbarSection;
import com.sduept.cim.model.wires.Compensator;
import com.sduept.cim.model.wires.DcLinesegment;
import com.sduept.cim.model.wires.PowerTransformer;
import com.sduept.core.ParamManager;
import com.sduept.core.entity.SystemParameter;
import com.sduept.message.entity.AlarmMessage;
import com.sduept.message.entity.AlarmMessageCheck;
import com.sduept.message.manager.AlarmMessageCheckManager;
import com.sduept.message.manager.AlarmMessageManager;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.nwld.dataserver.util.LibTreeNode;
import com.sduept.permission.entity.DepartmentEntityBean;
import com.sduept.permission.manager.DepartManager;

/**
 *
 */
@Named
@ViewScoped
public class AlarmMessageConfigController extends AbstractController {
	//TODO: 更换 了ManagementUnit 的管理类，需要优化
	private static final long serialVersionUID = 3389065766381526877L;
	@Autowired
	private RiskAlarmMessageQueryManager manager;
	@Autowired
	private DepartManager dm;
	@Autowired
	private SubstationLedgerManager stationLedgerM;
	@Autowired
	private CimManager cimM;
	@Autowired
	private AlarmMessageCheckManager alarmM;
	@Autowired
	private ParamManager pcache;
	@Autowired
	private AlarmMessageManager alarmMessageManager;

	private AlarmMessage alarmMessage = new AlarmMessage();
	private List<AlarmMessage> alarms = new ArrayList<>();
	private LazyDataModel<AlarmMessage> model;
	private AlarmMessage selected = null;
	private AlarmMessage created = null;
	private List<SystemParameter> msgTypeList = new ArrayList<SystemParameter>();
	private String statusQuery = null;
	private String typeQuery = null;
	private Date queryDate1;
	private Date queryDate2;

	private TreeNode stationRoot;
	private TreeNode stationSelectedNode;
	private TreeNode primaryRoot;
	private TreeNode primarySelectedNode;
	private TreeNode secondaryRoot;
	private TreeNode secondarySelectedNode;
	private Map<String, Substation> stationMap = new HashMap<String, Substation>();
	private String station;

	@PostConstruct
	public void init() {
		initMsgType();
		statusQuery = "0";
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar cal = Calendar.getInstance();
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		cal.add(Calendar.DATE, -1);
		Date d = cal.getTime();
		queryDate1 = d;
		queryDate2 = Calendar.getInstance().getTime();
		String startTime = format.format(queryDate1);
		String endTime = format.format(queryDate2).replace("00:00:00", "23:59:59");
		try {
			queryDate2 = sdf.parse(endTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		initTable(startTime, endTime, null);
		stationMap = getStationMap();
	}

	private void initMsgType() {
		String allTypes = pcache.get(ParamDesc.RISK_ALARM_TYPES).getValue();
		StringTokenizer token = new StringTokenizer(allTypes, ",");
		while (token.hasMoreTokens()) {
			SystemParameter param = pcache.get(token.nextToken());
			msgTypeList.add(param);
		}
	}

	private void initTable(final String startTime, final String endTime, final String msgType) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			queryDate2 = sdf.parse(endTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		model = new LazyDataModel<AlarmMessage>() {
			private static final long serialVersionUID = 7308651253648949103L;

			@Override
			public List<AlarmMessage> load(int first, int pageSize, String sortField, SortOrder sortOrder,
					Map<String, Object> filters) {
				alarms = manager.getAlarmMessageByTypeStatusDate(msgType,
						StringUtils.isNotEmpty(statusQuery) ? Integer.valueOf(statusQuery) : null, queryDate1,
						queryDate2, first, pageSize);
				if (alarms.size() > 0) {
					alarms = beautyLoadDate(alarms);
				}
				return alarms;
			}

			@Override
			public List<AlarmMessage> load(int first, int pageSize, List<SortMeta> multiSortMeta,
					Map<String, Object> filters) {
				alarms = manager.getAlarmMessageByTypeStatusDate(msgType,
						StringUtils.isNotEmpty(statusQuery) ? Integer.valueOf(statusQuery) : null, queryDate1,
						queryDate2, first, pageSize);
				return alarms;
			}

			@Override
			public AlarmMessage getRowData(String rowKey) {
				for (AlarmMessage t : alarms) {
					if (t.getId().equals(rowKey)) {
						return t;
					}
				}
				return null;
			}

			@Override
			public Object getRowKey(AlarmMessage object) {
				for (AlarmMessage t : alarms) {
					if (t.getId().equals(object.getId())) {
						return t;
					}
				}
				return null;
			}
		};
		long rowCount = manager.countByTypeStatusContentDate(msgType,
				StringUtils.isNotEmpty(statusQuery) ? Integer.valueOf(statusQuery) : null, null, queryDate1,
				queryDate2);
		model.setRowCount((int) rowCount);
	}

	public void query() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String startTime = "1970-01-01 00:00:00";
		String endTime = format.format(Calendar.getInstance().getTime());
		if (queryDate1 != null) {
			startTime = format.format(queryDate1);
		}
		if (queryDate2 != null) {
			endTime = format.format(queryDate2).replace("00:00:00", "23:59:59");
		}
		initTable(startTime, endTime, typeQuery);
		if (alarms.size() > 0) {
			alarms = beautyLoadDate(alarms);
		}
	}

	public void create() {
		created = new AlarmMessage();
		created.setCreateTime(new Date());
	}

	public void edit() {
		alarmMessage = selected;
		initStationTree();
	}

	public void save() {
		/*
		 * if (created != null) { created = manager.createAlarmMessage(created);
		 * alarms.add(0, created); created = null; } else
		 */
		if (selected != null) {
			if (StringUtils.isEmpty(selected.getStationName())) {
				selected.setStationId(null);
				selected.setStationName(null);
			}
			if (StringUtils.isEmpty(selected.getPrimaryName())) {
				selected.setPrimaryId(null);
				selected.setPrimaryName(null);
			}
			if (StringUtils.isEmpty(selected.getSecondaryName())) {
				selected.setSecondaryId(null);
				selected.setSecondaryName(null);
			}
			selected = alarmMessageManager.update(selected);
			// 同步修改AlarmMessageCheck
			AlarmMessageCheck alarmMessageCheck = alarmM.getAlarmMessageCheckByMsgId(selected.getId());
			if (null != alarmMessageCheck) {
				alarmMessageCheck.setMsgContent(selected.getContent());
				alarmM.saveAlarmMessageCheck(alarmMessageCheck);
			}
			selected = null;
		}
		query();
		addSuccessMessage("保存成功");
	}

	public void deleteById() {
		alarmMessageManager.delete(selected.getId());
		alarms.remove(selected);
		addSuccessMessage("删除成功！");
		selected = null;
		query();
	}

	/**
	 * 加载时，将数据库存储数据美化为显示数据
	 *
	 * @param alarms
	 * @return List<AlarmMessage>
	 */
	public List<AlarmMessage> beautyLoadDate(List<AlarmMessage> alarms) {
		if (alarms.size() > 0) {
			ListIterator<AlarmMessage> it = alarms.listIterator();
			while (it.hasNext()) {
				AlarmMessage a = it.next();
				/*
				 * if (a.getMsgType() != null && !a.getMsgType().equals("")) { String alarmType
				 * = manager.getAlarmTypeById(a.getMsgType()); a.setMsgType(alarmType); }
				 */
				// 添加过期信息
				long timeDifference = new Date().getTime() - a.getCreateTime().getTime();
				if (timeDifference > a.getTimeliness() || a.getStatus() == 1) {
					a.setStausText("已过期");
				} else {
					a.setStausText("未过期");
				}
			}
		}
		return alarms;
	}

	public String getDescriptionText(String type) {
		SystemParameter param = pcache.get(type);
		if (null != param) {
			return param.getDescription();
		} else {
			return null;
		}
	}

	public void overdueByHand() {
		if (selected != null) {
			long timeDifference = new Date().getTime() - selected.getCreateTime().getTime();
			if (timeDifference <= selected.getTimeliness()) {
				selected.setStatus(1);
				selected = alarmMessageManager.update(selected);
				alarms.remove(selected);
				addSuccessMessage("操作成功");
			} else {
				addErrorMessage("本条消息已过期");
			}
		}
		selected = null;
	}

	public void onRowSelect(SelectEvent event) {
		selected = (AlarmMessage) event.getObject();
	}

	/**
	 * 获取所有的（可用和不可用）的变电站（CimCache里的只查询可用的变电站）
	 *
	 * @return
	 */
	private Map<String, Substation> getStationMap() {
		List<Substation> allStationList = cimM.findUsedAndUnUsedStations();
		Map<String, Substation> stationMap = new HashMap<String, Substation>();
		for (Substation substation : allStationList) {
			stationMap.put(substation.getId(), substation);
		}
		return stationMap;
	}

	public void initStationTree() {
		stationRoot = new LibTreeNode("Root", null);
		// 组织机构的根节点，即南方电网
		List<DepartmentEntityBean> rootDepts = dm.findRootDepts();
		if (rootDepts.size() > 0) {
			DepartmentEntityBean rootDept = rootDepts.get(0);
			LibTreeNode root = new LibTreeNode("dept", rootDept, stationRoot);
			// 南方电网下一级节点
			List<DepartmentEntityBean> depts = dm.getDepartmentsByParent(rootDept.getId());
			for (DepartmentEntityBean dept : depts) {
				// 如果部门类型为调度单位，直接加入树中
				if (ManagementUnitEnum.DISPATCHING_MANAGEMENT.name().equals(dept.getType())) {
					new LibTreeNode("dept", dept, root);
				} else if (ManagementUnitEnum.MAINTENANCE_SCOPE.name().equals(dept.getType())) {
					// 如果部门类型为运维单位，则对其进行递归查找，看其子是否有调度单位类型
					recursionGetDesorgChildDept(dept, root);
				}
			}
			List<SubstationLedger> stationLedgers = stationLedgerM.queryStationLedgerByCondition(null, null,
					rootDept.getName(), null, "全部", null, "全部", "全部", "全部", null);
			for (SubstationLedger ledger : stationLedgers) {
				Substation station = stationMap.get(ledger.getCimId());
				new LibTreeNode("station", station, root);
			}
			root.setExpanded(true);
		}
	}

	private void recursionGetDesorgChildDept(DepartmentEntityBean dept, TreeNode treeNode) {
		// 获取该部门的直接子部门
		List<DepartmentEntityBean> depts = dm.getDepartmentsByParent(dept.getId());
		// 如果子部门为调度单位，直接加入树中
		for (DepartmentEntityBean d : depts) {
			if (ManagementUnitEnum.DISPATCHING_MANAGEMENT.name().equals(d.getType())) {
				new LibTreeNode("dept", d, treeNode);
			} else if (ManagementUnitEnum.MAINTENANCE_SCOPE.name().equals(d.getType())) {
				// 如果子部门为运维单位，递归判断该子部门下是否有调度单位
				recursionGetDesorgChildDept(d, treeNode);
			}
		}
	}

	public void initPrimaryTree() {
		primaryRoot = new LibTreeNode("Root", null);
		LibTreeNode root = new LibTreeNode();
		Substation station = new Substation();
		if (null != stationSelectedNode) {
			station = (Substation) stationSelectedNode.getData();
			root = new LibTreeNode("station", stationSelectedNode.getData(), primaryRoot);
		} else if (StringUtils.isNotEmpty(selected.getStationId())) {
			station = cimM.getStationById(selected.getStationId());
			root = new LibTreeNode("station", station, primaryRoot);
		} else {
			return;
		}
		if (null != station) {
			LibTreeNode busbarRoot = new LibTreeNode("type", "母线", root);
			List<BusbarSection> buasbarList = cimM.getBusbarSectionsByStationId(station.getId());
			for (BusbarSection busbarSection : buasbarList) {
				new LibTreeNode("equipment", busbarSection, busbarRoot);
			}
			LibTreeNode dcRoot = new LibTreeNode("type", "直流线路", root);
			List<DcLinesegment> dclines = cimM.getDcLineSegmentsBySubstation(station.getId());
			for (DcLinesegment dcLinesegment : dclines) {
				new LibTreeNode("equipment", dcLinesegment, dcRoot);
			}
			LibTreeNode acRoot = new LibTreeNode("type", "交流线路", root);
			List<ACLineSegment> acLines = cimM.getAcLineSegmentsBySubstation(station.getId());
			for (ACLineSegment acLine : acLines) {
				new LibTreeNode("equipment", acLine, acRoot);
			}
			LibTreeNode transRoot = new LibTreeNode("type", "变压器", root);
			List<PowerTransformer> transList = cimM.getPowerTransformersByStationId(station.getId());
			for (PowerTransformer powerTransformer : transList) {
				new LibTreeNode("equipment", powerTransformer, transRoot);
			}
			LibTreeNode comRoot = new LibTreeNode("type", "电抗器", root);
			List<Compensator> compList = cimM.getCompensatorsByStationId(station.getId());
			for (Compensator compensator : compList) {
				new LibTreeNode("equipment", compensator, comRoot);
			}
			LibTreeNode breakerRoot = new LibTreeNode("type", "断路器", root);
			List<Breaker> breakers = cimM.getBreakersByStationId(station.getId());
			for (Breaker breaker : breakers) {
				new LibTreeNode("equipment", breaker, breakerRoot);
			}
		}
		root.setExpanded(true);
	}

	public void initSecondaryTree() {
		secondaryRoot = new LibTreeNode("Root", null);
		LibTreeNode root = new LibTreeNode();
		Substation station = new Substation();
		if (null != stationSelectedNode) {
			station = (Substation) stationSelectedNode.getData();
			root = new LibTreeNode("station", stationSelectedNode.getData(), secondaryRoot);
		} else if (StringUtils.isNotEmpty(selected.getStationId())) {
			station = cimM.getStationById(selected.getStationId());
			root = new LibTreeNode("station", station, secondaryRoot);
		} else {
			return;
		}
		if (null != station) {
			LibTreeNode protectRoot = new LibTreeNode("type", "保护设备", root);
			List<ProtectionEquipment> protectionEquipments = cimM.getProtectionEquipmentsByStationId(station.getId());
			for (ProtectionEquipment protectionEquipment : protectionEquipments) {
				new LibTreeNode("equipment", protectionEquipment, protectRoot);
			}
		}
		root.setExpanded(true);
	}

	public void changeStation() {
		if (null != stationSelectedNode) {
			Substation station = (Substation) stationSelectedNode.getData();
			selected.setStationId(station.getId());
			selected.setStationName(station.getName());

			selected.setPrimaryId(null);
			selected.setPrimaryName(null);
			selected.setSecondaryId(null);
			selected.setSecondaryName(null);
		}
		genMsgContent();
	}

	public void changePrimary() {
		if (null != primarySelectedNode) {
			Equipment primary = (Equipment) primarySelectedNode.getData();
			selected.setPrimaryId(primary.getId());
			selected.setPrimaryName(primary.getName());
		}
		genMsgContent();
	}

	/**
	 * 如果手动输入一次设备，则一次设备id置为null
	 */
	public void editPrimaryName() {
		selected.setPrimaryId(null);
		genMsgContent();
	}

	public void changeSecondary() {
		if (null != secondarySelectedNode) {
			ProtectionEquipment secondary = (ProtectionEquipment) secondarySelectedNode.getData();
			selected.setSecondaryId(secondary.getId());
			selected.setSecondaryName(secondary.getName());
		}
		genMsgContent();
	}

	/**
	 * 如果手动输入二次设备，则二次设备id置为null
	 */
	public void editSecondaryName() {
		selected.setSecondaryId(null);
		genMsgContent();
	}

	public void onStationNodeExpand(NodeExpandEvent event) {
		TreeNode selectedNode = event.getTreeNode();
		if (selectedNode.getData() instanceof DepartmentEntityBean) {
			DepartmentEntityBean selected = (DepartmentEntityBean) selectedNode.getData();
			if (null != selected) {
				String id = selected.getId();
				if (StringUtils.isNotEmpty(id)) {
					List<DepartmentEntityBean> ds = dm.getDepartmentsByParent(id);
					for (DepartmentEntityBean dept : ds) {
						if (ManagementUnitEnum.DISPATCHING_MANAGEMENT.name().equals(dept.getType())) {
							new LibTreeNode("dept", dept, selectedNode);
						} else if (ManagementUnitEnum.MAINTENANCE_SCOPE.name().equals(dept.getType())) {
							// 如果子部门为运维单位，递归判断该子部门下是否有调度单位
							recursionGetDesorgChildDept(dept, selectedNode);
						}
					}
					List<SubstationLedger> stationLedgers = stationLedgerM.queryStationLedgerByCondition(null, null,
							selected.getName(), null, "全部", null, "全部", "全部", "全部", null);
					for (SubstationLedger ledger : stationLedgers) {
						Substation station = stationMap.get(ledger.getCimId());
						new LibTreeNode("station", station, selectedNode);
					}
				}
			}
		} else if (selectedNode.getData() instanceof Substation) {
			stationSelectedNode = selectedNode;
		}
	}

	public void onPrimaryNodeExpand(NodeExpandEvent event) {
	}

	public void onSecondaryNodeExpand(NodeExpandEvent event) {
	}

	public void onStationNodeSelect(NodeSelectEvent event) {
		if ("station".equals(event.getTreeNode().getType())) {
			stationSelectedNode = event.getTreeNode();
		}
	}

	public void onPrimaryNodeSelect(NodeSelectEvent event) {
		if ("equipment".equals(event.getTreeNode().getType())) {
			primarySelectedNode = event.getTreeNode();
		}
	}

	public void onSecondaryNodeSelect(NodeSelectEvent event) {
		if ("equipment".equals(event.getTreeNode().getType())) {
			secondarySelectedNode = event.getTreeNode();
		}
	}

	public void genMsgContent() {
		String msgContent = "";
		if (StringUtils.isNotEmpty(selected.getStationName())) {
			msgContent = selected.getStationName();
		}
		if (StringUtils.isNotEmpty(selected.getPrimaryName())) {
			msgContent += "/" + selected.getPrimaryName();
		}
		if (StringUtils.isNotEmpty(selected.getSecondaryName())) {
			msgContent += "/" + selected.getSecondaryName();
		}
		if (StringUtils.isNotEmpty(selected.getMsgType())) {
			SystemParameter param = pcache.get(selected.getMsgType());
			if (null != param) {
				msgContent += "，发生" + param.getDescription();
			}
		}
		selected.setContent(msgContent);
	}

	/**
	 * 变电站选择树增加快速筛选功能
	 * 
	 * @param event
	 */
	public void reGenStationTree(SelectEvent event) {
		Object item = event.getObject();
		if (null != item) {
			stationRoot = new DefaultTreeNode();
			List<Substation> stations = cimM.getStationByName(item.toString());
			for (Substation s : stations) {
				new LibTreeNode("station", s, stationRoot);
			}
		}
	}

	public void refreshStationTree() {
		initStationTree();
		station = null;
	}

	public AlarmMessage getAlarmMessage() {
		return alarmMessage;
	}

	public void setAlarmMessage(AlarmMessage alarmMessage) {
		this.alarmMessage = alarmMessage;
	}

	public List<AlarmMessage> getAlarms() {
		return alarms;
	}

	public void setAlarms(List<AlarmMessage> alarms) {
		this.alarms = alarms;
	}

	public AlarmMessage getSelected() {
		return selected;
	}

	public void setSelected(AlarmMessage selected) {
		this.selected = selected;
	}

	public AlarmMessage getCreated() {
		return created;
	}

	public void setCreated(AlarmMessage created) {
		this.created = created;
	}

	public List<SystemParameter> getMsgTypeList() {
		return msgTypeList;
	}

	public void setMsgTypeList(List<SystemParameter> msgTypeList) {
		this.msgTypeList = msgTypeList;
	}

	public String getStatusQuery() {
		return statusQuery;
	}

	public void setStatusQuery(String statusQuery) {
		this.statusQuery = statusQuery;
	}

	public String getTypeQuery() {
		return typeQuery;
	}

	public void setTypeQuery(String typeQuery) {
		this.typeQuery = typeQuery;
	}

	public Date getQueryDate1() {
		return queryDate1;
	}

	public void setQueryDate1(Date queryDate1) {
		this.queryDate1 = queryDate1;
	}

	public Date getQueryDate2() {
		return queryDate2;
	}

	public void setQueryDate2(Date queryDate2) {
		this.queryDate2 = queryDate2;
	}

	public LazyDataModel<AlarmMessage> getModel() {
		return model;
	}

	public void setModel(LazyDataModel<AlarmMessage> model) {
		this.model = model;
	}

	public TreeNode getStationRoot() {
		return stationRoot;
	}

	public void setStationRoot(TreeNode stationRoot) {
		this.stationRoot = stationRoot;
	}

	public TreeNode getStationSelectedNode() {
		return stationSelectedNode;
	}

	public void setStationSelectedNode(TreeNode stationSelectedNode) {
		this.stationSelectedNode = stationSelectedNode;
	}

	public TreeNode getPrimaryRoot() {
		return primaryRoot;
	}

	public void setPrimaryRoot(TreeNode primaryRoot) {
		this.primaryRoot = primaryRoot;
	}

	public TreeNode getPrimarySelectedNode() {
		return primarySelectedNode;
	}

	public void setPrimarySelectedNode(TreeNode primarySelectedNode) {
		this.primarySelectedNode = primarySelectedNode;
	}

	public TreeNode getSecondaryRoot() {
		return secondaryRoot;
	}

	public void setSecondaryRoot(TreeNode secondaryRoot) {
		this.secondaryRoot = secondaryRoot;
	}

	public TreeNode getSecondarySelectedNode() {
		return secondarySelectedNode;
	}

	public void setSecondarySelectedNode(TreeNode secondarySelectedNode) {
		this.secondarySelectedNode = secondarySelectedNode;
	}

	public String getStation() {
		return station;
	}

	public void setStation(String station) {
		this.station = station;
	}

}
